package com.cjh.mybatis11.executor.statement;

import com.cjh.mybatis11.executor.Executor;
import com.cjh.mybatis11.executor.parameter.ParameterHandler;
import com.cjh.mybatis11.executor.resultset.ResultSetHandler;
import com.cjh.mybatis11.mapping.BoundSql;
import com.cjh.mybatis11.mapping.MappedStatement;
import com.cjh.mybatis11.session.Configuration;
import com.cjh.mybatis11.session.ResultHandler;
import com.cjh.mybatis11.session.RowBounds;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @Descripton 语句处理器抽象基类
 * @Author cjh
 * @Date 2023/6/1 10:29
 */
public abstract class BaseStatementHandler implements StatementHandler {
    protected final Configuration configuration;
    protected final Executor executor;
    protected final MappedStatement mappedStatement;
    protected final Object parameterObject;
    protected final ResultSetHandler resultSetHandler;
    protected final ParameterHandler parameterHandler;
    protected final RowBounds rowBounds;

    protected BoundSql boundSql;

    public BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject,
                                RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {

        this.configuration = mappedStatement.getConfiguration();
        this.executor = executor;
        this.mappedStatement = mappedStatement;
        this.rowBounds = rowBounds;

        // step-11 新增判断，因为 update 不会传入 boundSql 参数，所以这里要做初始化处理
        if (boundSql == null) {
            boundSql  = mappedStatement.getBoundSql(parameterObject);
        }

        this.boundSql = boundSql;
        this.parameterObject = parameterObject;

        this.parameterHandler = configuration.newParameterHandler(mappedStatement,parameterObject,boundSql);
        this.resultSetHandler = this.configuration.newResultSetHandler(executor, mappedStatement, rowBounds, resultHandler, boundSql);


    }

    @Override
    public Statement prepare(Connection connection) throws SQLException {
        Statement statement = null;
        try {
//            实例化statement------这里是让真实的connection去prepareStatement（sql）---返回的是prepareStatement
            statement = instantiateStatement(connection);
//           参数设置 可以被抽取，提供配置
            statement.setQueryTimeout(350);
            statement.setFetchSize(10000);
            return statement;
        } catch (Exception e) {
            throw new RuntimeException("Error preparing statement.  Cause: " + e, e);

        }

    }

    protected abstract Statement instantiateStatement(Connection connection) throws SQLException;


}
